package main

import (
	"fmt"
	"io"
	"strings"
)

/*

在io包中，io.Reader的扩展接口和实现类型都有哪些？它们分别都有什么功用？

	1.在io包中，io.Reader的扩展接口有下面几种?
		1.io.ReadWriter：此接口既是io.Reader的扩展接口，也是io.Writer的扩展接口。换句话说，该接口定义了一组行为，包含且仅包含了基本的字节序列读取方法Read，和字节序列写入方法Write。
		2.io.ReadCloser：此接口除了包含基本的字节序列读取方法之外，还拥有一个基本的关闭方法Close。后者一般用于关闭数据读写的通路。这个接口其实是io.Reader接口和io.Closer接口的组合。
		3.io.ReadWriteCloser：很明显，此接口是io.Reader、io.Writer和io.Closer这三个接口的组合。
		4.io.ReadSeeker：此接口的特点是拥有一个用于寻找读写位置的基本方法Seek。更具体地说，该方法可以根据给定的偏移量基于数据的起始位置、末尾位置，或者当前读写位置去寻找新的读写位置。
	这个新的读写位置用于表明下一次读或写时的起始索引。Seek是io.Seeker接口唯一拥有的方法。
		5.io.ReadWriteSeeker：显然，此接口是另一个三合一的扩展接口，它是io.Reader、io.Writer和io.Seeker的组合。

	2.io包中的io.Reader接口的实现类型?
		1.*io.LimitedReader：此类型的基本类型会包装io.Reader类型的值，并提供一个额外的受限读取的功能。
	所谓的受限读取指的是，此类型的读取方法Read返回的总数据量会受到限制，无论该方法被调用多少次。这个限制由该类型的字段N指明，单位是字节。
		2.*io.SectionReader：此类型的基本类型可以包装io.ReaderAt类型的值，并且会限制它的Read方法，只能够读取原始数据中的某一个部分（或者说某一段）
		3.*io.teeReader：此类型是一个包级私有的数据类型，也是io.TeeReader函数结果值的实际类型。这个函数接受两个参数r和w，类型分别是io.Reader和io.Writer。
	其结果值的Read方法会把r中的数据经过作为方法参数的字节切片p写入到w。可以说，这个值就是r和w之间的数据桥梁，而那个参数p就是这座桥上的数据搬运者。
		4.io.multiReader：此类型也是一个包级私有的数据类型。类似的，io包中有一个名为MultiReader的函数，它可以接受若干个io.Reader类型的参数值，并返回一个实际类型为io.multiReader的结果值。
	当这个结果值的Read方法被调用时，它会顺序地从前面那些io.Reader类型的参数值中读取数据。因此，也可以称之为多对象读取器。


问题：io包中的接口都有哪些？它们之间都有着怎样的关系？
	io包中的核心接口只有 3 个，它们是：io.Reader、io.Writer和io.Closer。
	可以把io包中的简单接口分为四大类。这四大类接口分别针对于四种操作，即：读取、写入、关闭和读写位置设定。前三种操作属于基本的 I/O 操作。


 */

func main() {

	// 使用strings.NewReader创建了一个字符串读取器
	str := strings.NewReader("CopyN copies n bytes (or until an error) from src to dst. " +
		"It returns the number of bytes copied and the earliest error encountered while copying.")

	// new了一个字符串构建器，并将其赋予了变量dst
	dst :=new(strings.Builder)

	written, err := io.CopyN(dst, str, 58)
	if err != nil {
		fmt.Printf("error: %v\n", err)
	} else {
		fmt.Printf("Written(%d): %q\n", written, dst.String())
	}

}
